home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / Form / Sources / View.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  26.5 KB  |  774 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                View.cpp
  4. //    Release Version:    $ ODF 3 $
  5. //
  6. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "Form.hpp"
  11.  
  12. #ifndef VIEW_H
  13. #include "View.h"
  14. #endif
  15.  
  16. #ifndef PART_H
  17. #include "Part.h"
  18. #endif
  19.  
  20. #ifndef FRAME_H
  21. #include "Frame.h"
  22. #endif
  23.  
  24. #ifndef SCROLLED_H
  25. #include "ScrollEd.h"
  26. #endif
  27.  
  28. // ----- Framework Layer -----
  29.  
  30. #ifndef FWUTIL_H
  31. #include "FWUtil.h"
  32. #endif
  33.  
  34. #ifndef FWFRAME_H
  35. #include "FWFrame.h"
  36. #endif
  37.  
  38. #ifndef FWLISTBX_H
  39. #include "FWListBx.h"
  40. #endif
  41.  
  42. #ifndef FWBUTTON_H
  43. #include "FWButton.h"
  44. #endif
  45.  
  46. #ifndef FWEDVIEW_H
  47. #include "FWEdView.h"
  48. #endif
  49.  
  50. #ifndef FWPOPUP_H
  51. #include "FWPopup.h"
  52. #endif
  53.  
  54. #ifndef FWCLUSTR_H
  55. #include "FWClustr.h"
  56. #endif
  57.  
  58. #ifndef FWCONTXT_H
  59. #include "FWContxt.h"
  60. #endif
  61.  
  62. #ifndef FWSCLBAR_H
  63. #include "FWSclBar.h"
  64. #endif
  65.  
  66. #ifndef FWSTATIC_H
  67. #include "FWStatic.h"
  68. #endif
  69.  
  70. // ----- OS Layer -----
  71.  
  72. #ifndef FWMENU_H
  73. #include "FWMenu.h"
  74. #endif
  75.  
  76. #ifndef FWEVENT_H
  77. #include "FWEvent.h"
  78. #endif
  79.  
  80. #ifndef FWRECT_H
  81. #include "FWRect.h"
  82. #endif
  83.  
  84. #ifndef FWRECSHP_H
  85. #include "FWRecShp.h"
  86. #endif
  87.  
  88. #ifndef FWTXTSHP_H
  89. #include "FWTxtShp.h"
  90. #endif
  91.  
  92. #ifndef FWPICSHP_H
  93. #include "FWPicShp.h"        
  94. #endif
  95.  
  96. #ifndef FWALERT_H
  97. #include "FWAlert.h"            
  98. #endif
  99.  
  100. #ifndef FWRESOUR_H
  101. #include "FWResour.h"            
  102. #endif
  103.  
  104. // ----- OpenDoc Includes -----
  105.  
  106. #ifndef SOM_Module_OpenDoc_Commands_defined
  107. #include <CmdDefs.xh>
  108. #endif
  109.  
  110. #ifndef SOM_Module_OpenDoc_StdProps_defined
  111. #include <StdProps.xh>
  112. #endif
  113.  
  114. #ifndef SOM_ODSession_xh
  115. #include <ODSessn.xh>
  116. #endif
  117.  
  118. #ifndef SOM_ODDispatcher_xh
  119. #include <Disptch.xh>
  120. #endif
  121.  
  122. //========================================================================================
  123. // RunTime Info
  124. //========================================================================================
  125.  
  126. #ifdef FW_BUILD_MAC
  127. #pragma segment odfform
  128. #endif
  129.  
  130. FW_DEFINE_CLASS_M1(CFormView, FW_CPictSView)
  131. FW_DEFINE_AUTO(CFormView)
  132.  
  133. #if FW_ODFRC_VIEWS
  134. const FW_ClassTypeConstant LFormView = FW_TYPE_CONSTANT('F','r','m','v');
  135. FW_REGISTER_ARCHIVABLE_CLASS(LFormView, CFormView, CFormView::Create, FW_CView::Read, CFormView::Destroy, FW_CView::Write)
  136. #endif
  137.  
  138. //========================================================================================
  139. // CFormView
  140. //========================================================================================
  141.  
  142. //----------------------------------------------------------------------------------------
  143. // CFormView::CFormView
  144. //----------------------------------------------------------------------------------------
  145.  
  146. CFormView::CFormView(Environment* ev, 
  147.                         FW_CSuperView* container,
  148.                         const FW_CRect& bounds,
  149.                         FW_ResourceID pictID1,
  150.                         FW_ResourceID pictID2) :
  151.     FW_CPictSView(ev, container, bounds, kFormViewID, pictID1, FW_kZeroPoint, FW_kXYScrolling),
  152.     fFirstFormOn(true)
  153. {    
  154.     // Adjust the bounds but don't redraw now 
  155.     CenterInFrame(ev, bounds.Size(), FW_kDontRedraw);
  156.     
  157.     InitializePict(ev, pictID2);
  158. }
  159.  
  160. //----------------------------------------------------------------------------------------
  161. // CFormView::CFormView
  162. //----------------------------------------------------------------------------------------
  163.  
  164. CFormView::CFormView(Environment* ev) :
  165.     FW_CPictSView(ev),
  166.     fFirstFormOn(true)
  167. {    
  168.     // Adjust the bounds but don't redraw now 
  169. //     CenterInFrame(ev, contentRect.Size(), FALSE);  can do that here?
  170. }
  171.  
  172. //----------------------------------------------------------------------------------------
  173. // CFormView::~CFormView
  174. //----------------------------------------------------------------------------------------
  175.  
  176. CFormView::~CFormView()
  177. {
  178. }
  179.  
  180. //----------------------------------------------------------------------------------------
  181. // CFormView::InitializePict
  182. //----------------------------------------------------------------------------------------
  183.  
  184. void CFormView::InitializePict(Environment* ev, FW_ResourceID pictID) 
  185. {    
  186.     FW_TRY
  187.     {
  188.         // Load the 2nd picture from the part shared library
  189.         FW_PSharedLibraryResourceFile resFile(ev);
  190.         fPicture2 = FW_CPicture(resFile, pictID);
  191.     }
  192.     FW_CATCH_BEGIN
  193.     FW_CATCH_REFERENCE(FW_XException, except)
  194.     {
  195.         // Picture will be replaced by message "Picture not found!"
  196.         fPicture2 = 0;
  197.     }
  198.     FW_CATCH_END
  199. }
  200.  
  201. //----------------------------------------------------------------------------------------
  202. // CFormView::ActivateTarget
  203. //----------------------------------------------------------------------------------------
  204. // ActivateTarget is called the first time the frame gets the selection focus (because
  205. // a content view is always the frame's default target). We use this to change the target 
  206. // to be the first text-edit field, i.e. to activate this field for keyboard events.
  207.  
  208. void CFormView::ActivateTarget(Environment* ev, FW_Boolean tabSelection)
  209. {
  210.     FW_CView* edview = FindViewByID(ev, kFirstNameEdViewID);
  211.     
  212.     // Be sure that the edit view wants to be the target before doing it
  213.     // (otherwise it would be activated even when it's invisible in the 2nd form)
  214.      
  215.     if (edview->WantsToBeTarget(ev))
  216.         edview->BecomeTarget(ev, tabSelection);
  217. }
  218.  
  219. //----------------------------------------------------------------------------------------
  220. //    CFormView::PostCreateViewFromStream
  221. //----------------------------------------------------------------------------------------
  222. // PostCreateViewFromStream is called after subviews are created from resources.  
  223. // Implement initializations for this view that can't be done from a stream.
  224.  
  225. void CFormView::PostCreateViewFromStream(Environment* ev)
  226. {
  227.     // ----- Link the frame to the list-box in order to respond to double-clicks
  228.     //        (standard controls are linked by defining their "receiver" resource field)
  229.     
  230.     // Note: this code could also reside in CFormFrame::PostCreateViewFromStream
  231.     //         if you prefer to do all PostCreate initializations in one place.
  232.     
  233.     CFormFrame* frame = (CFormFrame*)GetFrame(ev);
  234.     FW_CListBox* listbox = (FW_CListBox*)FindViewByID(ev, kPlatformListBoxID);
  235.     FW_ASSERT(listbox);
  236.     
  237.     frame->AddInterest(listbox, FW_kListBoxDoubleClickedMsg);
  238.     
  239.     // ----- Add a behavior to the list-box to handle mouse clicks
  240.     //        (easier than subclassing FW_CListBox and defining a new resource type)
  241.     
  242.     CMouseUpBehavior* behavior = FW_NEW(CMouseUpBehavior, (ev, listbox));
  243.     listbox->AdoptEventHandler(ev, behavior);
  244.     
  245.     // ----- Disable the "Remove" button by default
  246.     FW_CButton* rmButton = (FW_CButton*) FindViewByID(ev, kRemoveButtonID);
  247.     rmButton->Disable(ev);
  248.     
  249. #if FW_PPOB_VIEWS
  250.     // Constructor doesn't let you initialize the list-box items so we must do it here
  251.     // (we use AddStringItem because the number of items wasn't initialized either)
  252.     listbox->SetDrawingMode(ev, FALSE);
  253.     listbox->AddStringItem(ev, FW_CString("Mac OS"));
  254.     listbox->AddStringItem(ev, FW_CString("OS/2 Warp"));
  255.     listbox->AddStringItem(ev, FW_CString("Windows 95"));
  256.     listbox->AddStringItem(ev, FW_CString("Windows NT"));
  257.     listbox->AddStringItem(ev, FW_CString("IBM AIX"));
  258.     listbox->AddStringItem(ev, FW_CString("Sun Sparc Solaris"));
  259.     listbox->AddStringItem(ev, FW_CString("Sun OS 4.1.x"));
  260.     listbox->AddStringItem(ev, FW_CString("HP /UX"));
  261.     listbox->AddStringItem(ev, FW_CString("Unix IRIX"));
  262.     listbox->AddStringItem(ev, FW_CString("Unix Linux"));
  263.     listbox->SetDrawingMode(ev, TRUE);
  264. #endif
  265. }
  266.  
  267. //----------------------------------------------------------------------------------------
  268. // CFormView::CreateSubViews
  269. //----------------------------------------------------------------------------------------
  270. // Called from CFormFrame::CreateSubViews if compiled without using view resources
  271.  
  272. void CFormView::CreateSubViews(Environment* ev)
  273. {
  274. FW_UNUSED(ev);
  275. #if !FW_ODFRC_VIEWS && !FW_PPOB_VIEWS
  276.  
  277.     // This code is compiled only if you didn't define any of the 2 FW_XXX_VIEWS flags
  278.     // NOTE: You'll may get an "Out of memory" error if you don't have a LOT of memory on
  279.     // your Mac. It must be caused by the full-optimization flags used in Release mode.
  280.     FW_Fixed fixed20     = FW_IntToFixed(20);
  281.     FW_Fixed fixed40     = FW_IntToFixed(40);
  282.     FW_CFont timesBold(FW_kTimes, FW_kBold, FW_IntToFixed(12));
  283.     FW_CFont helvetica(FW_kHelvetica, FW_kPlain, FW_IntToFixed(12));
  284.  
  285.     FW_CRect viewRect;        // working rect for creating the views
  286.  
  287.     // ----- Create edit fields in the content view
  288.     viewRect.Set(FW_IntToFixed(290), FW_IntToFixed(90), FW_IntToFixed(450), FW_IntToFixed(107));
  289.     FW_CPoint offset(FW_kFixed0, fixed20);
  290.     for (int i = 0; i < 4; i++) {
  291.         FW_CEditView* editView = FW_NEW(FW_CEditView, (ev, this, kFirstNameEdViewID+i, viewRect));
  292.         editView->SetFont(ev, timesBold);
  293.         viewRect += offset;
  294.     }
  295.     
  296.     // ----- Create custom scrolling edit view with its scrollbar
  297.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(200), FW_IntToFixed(450), FW_IntToFixed(290));    
  298.     FW_CRect vertSbRect(viewRect.right - FW_kFixedPos1, viewRect.top, 
  299.                         viewRect.right + FW_IntToFixed(15), viewRect.bottom);
  300.     FW_CScrollBar* vertSB = FW_NEW(FW_CScrollBar, (ev, this, kEditVScrollBarID, vertSbRect));
  301.     vertSB->SetBindings(ev, FW_kFixedBounds);
  302.     CScrollEdit* scrollEdit = FW_NEW(CScrollEdit, (ev, this, kFirstNameEdViewID+4, viewRect, NULL, vertSB, FW_CString()));
  303.  
  304.     // ----- Create the "Subscribe" check box 
  305.     //         Use null message (no receiver) and initial value of 1 to turn it on
  306.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(310), FW_IntToFixed(200), FW_IntToFixed(324));
  307.     FW_CButton* check = FW_NEW(FW_CButton, (ev, this, kSubscribeCheckID, viewRect, FW_kCheckButton, 
  308.                                 FW_CString("Subscribe to ODFFlash"), timesBold, 0, 1));
  309.  
  310.     // ----- Create a list box (helvetica font, multiple selections, answer to double-clicks)
  311.     viewRect.Set(FW_IntToFixed(250), FW_IntToFixed(362), FW_IntToFixed(400), FW_IntToFixed(440));
  312.     FW_CListBox* listbox = FW_NEW(FW_CListBox, (ev, this, viewRect, kPlatformListBoxID, 10, 
  313.                                     true, helvetica, FW_kListBoxDoubleClickedMsg, false));
  314.     listbox->SetDrawingMode(ev, FALSE);
  315.     listbox->SetStringItem(ev, 1, FW_CString("Mac OS"));
  316.     listbox->SetStringItem(ev, 2, FW_CString("OS/2 Warp"));
  317.     listbox->SetStringItem(ev, 3, FW_CString("Windows 95"));
  318.     listbox->SetStringItem(ev, 4, FW_CString("Windows NT"));
  319.     listbox->SetStringItem(ev, 5, FW_CString("IBM AIX"));
  320.     listbox->SetStringItem(ev, 6, FW_CString("Sun Sparc Solaris"));
  321.     listbox->SetStringItem(ev, 7, FW_CString("Sun OS 4.1.x"));
  322.     listbox->SetStringItem(ev, 8, FW_CString("HP /UX"));
  323.     listbox->SetStringItem(ev, 9, FW_CString("Unix IRIX"));
  324.     listbox->SetStringItem(ev, 10, FW_CString("Unix Linux"));
  325.     listbox->SetDrawingMode(ev, TRUE);
  326.     
  327.     // ----- Create the Add/Remove buttons
  328.     viewRect.Set(FW_IntToFixed(410), FW_IntToFixed(370), FW_IntToFixed(480), FW_IntToFixed(390));
  329.     FW_CButton* addButton = FW_NEW(FW_CButton, (ev, this, kAddButtonID, viewRect, 
  330.                                         FW_kPushButton, FW_CString("Add")));
  331.     viewRect.Set(FW_IntToFixed(410), FW_IntToFixed(400), FW_IntToFixed(480), FW_IntToFixed(420));
  332.     FW_CButton* removeButton = FW_NEW(FW_CButton, (ev, this, kRemoveButtonID, viewRect, 
  333.                                         FW_kPushButton, FW_CString("Remove")));
  334.     removeButton->Disable(ev);
  335.     
  336.     // ----- Create the "browsing time" popup
  337.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(477), FW_IntToFixed(230), FW_IntToFixed(497));
  338.     FW_CPopupMenu* popup1 = FW_NEW(FW_CPopupMenu, (ev, this, kBrowseTimePopupID, viewRect, 
  339.                                         kBrowseTimeMenuResID, FW_CString()));
  340.  
  341.     // ----- Create the "online time" popup
  342.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(540), FW_IntToFixed(230), FW_IntToFixed(560));
  343.     FW_CPopupMenu* popup2 = FW_NEW(FW_CPopupMenu, (ev, this, kOnlineTimePopupID, viewRect, 
  344.                                         kOnlineTimeMenuResID, FW_CString()));
  345.  
  346.     // ----- Create the "First Discover" radio butttons & their radio cluster
  347.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(580), FW_IntToFixed(350), FW_IntToFixed(700));
  348.     FW_CGroupBox* discoverGroupB = FW_NEW(FW_CGroupBox, (ev, this, viewRect, 
  349.                                         FW_CString(" How did you discover ODFWired?"), timesBold));
  350.  
  351.     viewRect.Set(fixed40, FW_IntToFixed(600), FW_IntToFixed(300), FW_IntToFixed(616));
  352.     FW_CButton* radio4 = FW_NEW(FW_CButton, (ev, this, kWorldMouthRadioID, viewRect, 
  353.                                         FW_kRadioButton, FW_CString("Word of mouth")));
  354.     viewRect.Offset(FW_kFixed0, fixed20);
  355.     FW_CButton* radio5 = FW_NEW(FW_CButton, (ev, this, kHyperLinkRadioID, viewRect, 
  356.                                         FW_kRadioButton, FW_CString("Hyperlink from another site:")));
  357.     viewRect.Offset(FW_kFixed0, fixed20);
  358.     FW_CButton* radio6 = FW_NEW(FW_CButton, (ev, this, kMacTechRadioID, viewRect, 
  359.                                         FW_kRadioButton, FW_CString("Ad in MacTech Magazine")));
  360.     viewRect.Offset(FW_kFixed0, fixed20);
  361.     FW_CButton* radio7 = FW_NEW(FW_CButton, (ev, this, kMagazineRadioID, viewRect, 
  362.                                         FW_kRadioButton, FW_CString("Other magazine, newspaper, radio")));
  363.     viewRect.Offset(FW_kFixed0, fixed20);
  364.     FW_CButton* radio8 = FW_NEW(FW_CButton, (ev, this, kOtherRadioID, viewRect, 
  365.                                         FW_kRadioButton, FW_CString("Other")));
  366.     radioCluster = FW_NEW(FW_CRadioCluster, (ev));
  367.     radioCluster->AddRadio(ev, radio4);
  368.     radioCluster->AddRadio(ev, radio5);
  369.     radioCluster->AddRadio(ev, radio6);
  370.     radioCluster->AddRadio(ev, radio7);
  371.     radioCluster->AddRadio(ev, radio8);
  372.     
  373.     // ----- Create the "using OpenDoc" radio butttons & their radio cluster
  374.     viewRect.Set(fixed40, FW_IntToFixed(725), FW_IntToFixed(100), FW_IntToFixed(740));
  375.     FW_CButton* radio9 = FW_NEW(FW_CButton, (ev, this, kYesRadioID, viewRect, 
  376.                                         FW_kRadioButton, FW_CString("Yes")));
  377.     viewRect.Offset(FW_kFixed0, fixed20);
  378.     FW_CButton* radio10 = FW_NEW(FW_CButton, (ev, this, kNoRadioID, viewRect, 
  379.                                         FW_kRadioButton, FW_CString("No")));
  380.     radioCluster = FW_NEW(FW_CRadioCluster, (ev));
  381.     radioCluster->AddRadio(ev, radio9);
  382.     radioCluster->AddRadio(ev, radio10);
  383.  
  384.     // ----- Create the "Subscribe" button at the bottom of the content view
  385.     FW_CString label("Join ODFWired!");
  386.     viewRect.Set(FW_IntToFixed(300), FW_IntToFixed(750), FW_IntToFixed(450), FW_IntToFixed(775));
  387.     FW_CButton* pushButton = FW_NEW(FW_CButton, (ev, this, kSubscribeButtonID, viewRect, 
  388.                                         FW_kPushButton, label));
  389.  
  390.     // ----- Link the frame to the controls it wants to respond to
  391.     //        (CFormFrame was defined as an FW_MReceiver and thus can respond to
  392.     //        notitications.  We could also have decided to make CFormView the
  393.     //        receiver, it's a matter of choice)
  394.     CFormFrame* frame = (CFormFrame*)GetFrame(ev);
  395.     
  396.     pushButton->LinkControlTo(ev, frame);
  397.     addButton->LinkControlTo(ev, frame);
  398.     removeButton->LinkControlTo(ev, frame);
  399.     radio10->LinkControlTo(ev, frame);
  400.     popup1->LinkControlTo(ev, frame);
  401.     
  402.     frame->AddNotifier(listbox, FW_kListBoxDoubleClickedMsg);
  403.  
  404.     // ----- Add a behavior to the list-box to handle mouse clicks
  405.     //        (easier than subclassing FW_CListBox and defining a new resource type)    
  406.     CMouseUpBehavior* behavior = FW_NEW(CMouseUpBehavior, (ev, listbox));
  407.     listbox->AdoptEventHandler(ev, behavior);
  408. #endif
  409. }
  410.  
  411. //----------------------------------------------------------------------------------------
  412. // CFormView::Draw
  413. //----------------------------------------------------------------------------------------
  414.  
  415. void CFormView::Draw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  416. {
  417.     if (fFirstFormOn)
  418.         inherited::Draw(ev, odFacet, invalidShape);
  419.     else 
  420.     {
  421.         // Draw the 2nd picture and the data entered by the user
  422.         inherited::DrawAnotherPicture(ev, odFacet, invalidShape, fPicture2);
  423.  
  424.         FW_CViewContext    vc(ev, this, odFacet, invalidShape);
  425.         DrawUserData(ev, vc);
  426.     }
  427.     
  428.     // SubViews of CFormView are drawn recursively after this point.
  429.     
  430.     // Mac Note: If you want to draw Controls with a non-white background color to match
  431.     // the color of their parent view, you need either to define a color table for
  432.     // the window (see CPwdDialogFrame::FacetAdded for an example) or define color tables
  433.     // for individual controls.  See "Inside Macintosh: Macintosh Toolbox Essentials".
  434. }
  435.  
  436. //----------------------------------------------------------------------------------------
  437. // CFormView::CenterInFrame
  438. //----------------------------------------------------------------------------------------
  439.  
  440. #define VALUE_WITH_LOWER_LIMIT(VALUE,LIMIT) (((VALUE) < (LIMIT)) ? (LIMIT) : (VALUE))
  441. #define VALUE_WITH_UPPER_LIMIT(VALUE,LIMIT) (((VALUE) > (LIMIT)) ? (LIMIT) : (VALUE))
  442.  
  443. void CFormView::CenterInFrame (Environment* ev, FW_CPoint& superViewSize, FW_ERedrawVerb redraw)
  444. {
  445.     //
  446.     // Center this view inside its parent view
  447.     //
  448.     
  449.     FW_CRect superViewSpace (FW_kZeroPoint, superViewSize);
  450.     if (GetFrame(ev)->IsRoot(ev) == FALSE) {
  451.         superViewSpace.TopLeft() += FW_CPoint(FW_kFixedPos1,FW_kFixedPos1);
  452.         superViewSize = superViewSpace.Size();
  453.     }
  454.     
  455.     FW_CPoint logicalSize (GetExtent(ev));
  456.     
  457.     // Beware of a printing clipping bug: the content view has to be at 0,0
  458.     // Therefore don't center if we're not dynamic (i.e. printing).
  459.     Boolean isDynamic = GetFrame(ev)->GetActiveFacet(ev)->GetCanvas(ev)->IsDynamic(ev);
  460.     FW_CPoint unusedSpaceForCentering = FW_kZeroPoint;
  461.     if (isDynamic) {
  462.         unusedSpaceForCentering.x = VALUE_WITH_LOWER_LIMIT (superViewSize.x - logicalSize.x, FW_kFixed0);
  463.         unusedSpaceForCentering.y = VALUE_WITH_LOWER_LIMIT (superViewSize.y - logicalSize.y, FW_kFixed0);
  464.     }
  465.     
  466.     // Position in middle of unused space
  467.     FW_CPoint physicalLocation;
  468.     physicalLocation.x = superViewSpace.left + FW_Half (unusedSpaceForCentering.x);
  469.     physicalLocation.y = superViewSpace.top + FW_Half (unusedSpaceForCentering.y);
  470.     
  471.     // Expand as much as superViewSize allows, up to full logicalSize
  472.     FW_CPoint physicalSize;
  473.     physicalSize.x = VALUE_WITH_UPPER_LIMIT (superViewSize.x, logicalSize.x);
  474.     physicalSize.y = VALUE_WITH_UPPER_LIMIT (superViewSize.y, logicalSize.y);
  475.     
  476.     SetLocation (ev, physicalLocation, redraw);
  477.     SetSize (ev, physicalSize, redraw);
  478. }
  479.  
  480.  
  481. //----------------------------------------------------------------------------------------
  482. // CFormView::AdjustToNewLayout
  483. //----------------------------------------------------------------------------------------
  484.  
  485. void CFormView::AdjustToNewLayout(Environment *ev, const FW_CPoint& oldExtent, 
  486.                                     const FW_CPoint& newExtent, FW_ERedrawVerb redraw)    
  487. {
  488.     FW_UNUSED (oldExtent);
  489.  
  490.     // newExtent is the (logical) size of our parent view
  491.     FW_CPoint size = newExtent;
  492.     
  493.     CenterInFrame(ev, size, redraw);
  494.     
  495.     return;
  496. }
  497.  
  498. //----------------------------------------------------------------------------------------
  499. // CFormView::DoMouseDown
  500. //----------------------------------------------------------------------------------------
  501.  
  502. FW_Handled CFormView::DoMouseDown(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  503. {
  504. FW_UNUSED(theMouseEvent);
  505.     // Go back to the first form when clicking on the 2nd one
  506.     if (!fFirstFormOn)
  507.         SwitchForm(ev);
  508.  
  509.     return FW_kHandled;
  510. }
  511.  
  512. //----------------------------------------------------------------------------------------
  513. // CFormView::SwitchForm
  514. //----------------------------------------------------------------------------------------
  515.  
  516. void     CFormView::SwitchForm(Environment* ev)
  517. {
  518.     if (fFirstFormOn)
  519.     {
  520.         fFirstFormOn = FALSE;
  521.         
  522.         // Hide all subviews but don't hide the form view itself
  523.         SetVisible(ev, FALSE, TRUE);
  524.         SetVisible(ev, TRUE, FALSE);
  525.     }
  526.     else
  527.     {
  528.         fFirstFormOn = TRUE;
  529.         
  530.         // Show all subviews
  531.         SetVisible(ev, TRUE, TRUE);
  532.         
  533.     }
  534.     
  535.     // Force a redraw
  536.     Invalidate(ev);
  537. }
  538.  
  539. //----------------------------------------------------------------------------------------
  540. // CFormView::DrawUserData
  541. //----------------------------------------------------------------------------------------
  542.  
  543. void CFormView::DrawUserData(Environment *ev, FW_CViewContext& vc)
  544. {
  545.     FW_CPoint        position;
  546.     FW_Fixed         vDelta = FW_IntToFixed(24);
  547.     int                i;
  548.     
  549.     FW_CString        str;
  550.     FW_CString        yesStr("Yes");
  551.     FW_CString        noStr("No");
  552.     
  553.     position.x = FW_IntToFixed(200);
  554.     position.y = FW_IntToFixed(90);
  555.  
  556.     // Edit views
  557.     FW_CEditView*    edview;
  558.     for (i = 0; i < 4; i++)
  559.     {
  560.         edview = (FW_CEditView*)FindViewByID(ev, kFirstNameEdViewID+i);
  561.         str = edview->GetText(ev);
  562.         FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  563.         position.y += vDelta;
  564.     }
  565.     
  566.     // Check box
  567.     FW_CButton*        button;
  568.     button = (FW_CButton*)FindViewByID(ev, kSubscribeCheckID);
  569.     FW_CTextShape::RenderText(vc, button->GetState(ev) ? yesStr : noStr, position, FW_kNormalFont);
  570.     position.y += vDelta;
  571.     
  572.     // Popups
  573.     FW_CPopupMenu* popup1 = (FW_CPopupMenu*) FindViewByID(ev, kBrowseTimePopupID);
  574.     popup1->GetMenuString(ev, str);
  575.     FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  576.     position.y += vDelta;
  577.  
  578.     FW_CPopupMenu* popup2 = (FW_CPopupMenu*) FindViewByID(ev, kOnlineTimePopupID);
  579.     popup2->GetMenuString(ev, str);
  580.     FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  581.     position.y += vDelta;
  582.     
  583.     // Radio buttons (they are all ordered by ids)
  584.     CFormFrame*    frame = (CFormFrame*) GetFrame(ev);
  585.  
  586.     for (i = 0; i < kNumRadioButtons; i++)
  587.     {
  588.         button = (FW_CButton*)FindViewByID(ev, kFirstRadioID + i);
  589.         if (button->GetState(ev)) 
  590.         {
  591.             button->GetLabel(ev, str);
  592.             FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  593.             position.y += vDelta;
  594.         }
  595.     }
  596.     
  597.     // List box
  598.     FW_CListBox* list = (FW_CListBox*)FindViewByID(ev, kPlatformListBoxID);
  599.     const short maxPlaforms = 10;
  600.     short platforms[maxPlaforms];
  601.     short numSelected = list->GetSelectedItems(ev, maxPlaforms, platforms);
  602.     if (numSelected > 0)
  603.     {
  604.         for (i = 0; i < numSelected; i++)
  605.         {
  606.             list->GetStringItem(ev, platforms[i], str);
  607.             FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);            
  608.             position.y += FW_IntToFixed(16);
  609.         }
  610.     }
  611.     
  612. }
  613.  
  614. //----------------------------------------------------------------------------------------
  615. // CFormView::ResetData
  616. //----------------------------------------------------------------------------------------
  617.  
  618. void CFormView::ResetData(Environment *ev)
  619. {
  620.     // Erase the text of the 5 edit views
  621.     FW_CEditView*    edview;
  622.     for (int i = 0; i < 4; i++)
  623.     {
  624.         edview = (FW_CEditView*)FindViewByID(ev, kFirstNameEdViewID+i);
  625.         edview->SetText(ev, FW_CString());
  626.     }
  627.     
  628.     CScrollEdit* scrolledit = (CScrollEdit*)FindViewByID(ev, kFirstNameEdViewID+4);
  629.     scrolledit->SetText(ev, FW_CString());
  630. }
  631.  
  632. //========================================================================================
  633. //    Archiving API with ODFRC resources
  634. //========================================================================================
  635. #if FW_ODFRC_VIEWS
  636.  
  637. //----------------------------------------------------------------------------------------
  638. //    CFormView::Create
  639. //----------------------------------------------------------------------------------------
  640.  
  641. void* CFormView::Create(FW_CReadableStream& stream, FW_ClassTypeConstant type)
  642. {
  643. FW_UNUSED(stream);
  644. FW_UNUSED(type);
  645.     FW_SOMEnvironment ev;
  646.     return FW_NEW(CFormView, (ev));
  647. }
  648.  
  649. //----------------------------------------------------------------------------------------
  650. //    CFormView::Destroy
  651. //----------------------------------------------------------------------------------------
  652.  
  653. void CFormView::Destroy(void* object, FW_ClassTypeConstant type)
  654. {
  655. FW_UNUSED(type);
  656.     CFormView* self = (CFormView*) object;
  657.     delete self;
  658. }
  659.  
  660. //----------------------------------------------------------------------------------------
  661. //    CFormView::Flatten
  662. //----------------------------------------------------------------------------------------
  663.  
  664. void CFormView::Flatten(Environment* ev, FW_CWritableStream& archive) const
  665. {
  666.     FW_CPictSView::Flatten(ev, archive);
  667.     
  668.     // [LSD] to complete
  669. }
  670.  
  671. //----------------------------------------------------------------------------------------
  672. //    CFormView::InitializeFromStream
  673. //----------------------------------------------------------------------------------------
  674. // This method is required to handle the custom resource fields added to the base type
  675.  
  676. void CFormView::InitializeFromStream(Environment* ev, FW_CReadableStream& stream)
  677. {
  678.     // Read-in the base resource first
  679.     FW_CPictSView::InitializeFromStream(ev, stream);
  680.     
  681.     // Initialize the 2nd picture
  682.     FW_ResourceID pictID2;
  683.     stream >> pictID2;
  684.     
  685.     InitializePict(ev, pictID2);
  686.     
  687.     // Read-in the 3 radio-clusters defined in our RFormView type in "Views.fr"
  688.     // (not need to keep them around).
  689.     FW_CRadioCluster* radioCluster;
  690.     
  691.     for (int i = 0; i < kNumRadioClusters; i++) 
  692.     {
  693.         FW_READ_DYNAMIC_OBJECT(stream, &radioCluster, FW_CRadioCluster);
  694.     }    
  695. }
  696.  
  697. #endif // FW_ODFRC_VIEWS
  698.  
  699. //========================================================================================
  700. // MetroWerks Constructor View Resource Reader
  701. //========================================================================================
  702. #if FW_PPOB_VIEWS
  703.  
  704. void ReadFormView (Environment* ev, FW_CPPobReader* context, FW_CReadableStream& stream)
  705. {
  706.     // Read the basic LPicture data. FWPPobOb.h doesn't define an LPicture
  707.     // struct since it only has one field; we'll just read them both.
  708.     
  709.     FW_SPPobViewInfo info (stream);
  710.     
  711.     // and our extra field
  712.     FW_ResourceID pict1, pict2;
  713.     stream >> pict1 >> pict2;
  714.     
  715.     CFormView* view = FW_NEW (CFormView, (ev, context->GetSuperView(), info.fBounds, pict1, pict2));
  716.     view->SetBindings (ev, info.fBindings);
  717.     context->SetNextSuperView (view);
  718. }
  719.  
  720. #endif // FW_PPOB_VIEWS
  721.  
  722. //========================================================================================
  723. //    class CMouseUpBehavior
  724. //========================================================================================
  725. // Event handler class used to customize the mouse-click action in our list-box.
  726. // Having a behavior allows us to not have to subclass FW_CListBox (and also not to have
  727. // to define a new resource type in the .fr file)
  728.  
  729. FW_DEFINE_AUTO(CMouseUpBehavior)
  730.  
  731. //----------------------------------------------------------------------------------------
  732. //    CMouseUpBehavior::CMouseUpBehavior
  733. //----------------------------------------------------------------------------------------
  734.  
  735. CMouseUpBehavior::CMouseUpBehavior(Environment* ev, FW_CListBox* listBox) :
  736.     FW_MEventHandler(ev, NULL, FW_kNoPriority),
  737.     fListBox(listBox)
  738. {
  739.     FW_END_CONSTRUCTOR
  740. }
  741.  
  742. //----------------------------------------------------------------------------------------
  743. //    CMouseUpBehavior::~CMouseUpBehavior
  744. //----------------------------------------------------------------------------------------
  745.  
  746. CMouseUpBehavior::~CMouseUpBehavior() 
  747. {
  748.     FW_START_DESTRUCTOR
  749. }
  750.  
  751. //----------------------------------------------------------------------------------------
  752. //    CMouseUpBehavior::DoMouseUp
  753. //----------------------------------------------------------------------------------------
  754. // We use the mouse up event to check if the listbox has 1 or more selected items
  755. // and enable the "Delete" button in that case.
  756. // (In that case we cannot use a mouse down event behavior because it would be executed
  757. //  before the listbox's mouse down handler, see FW_MEventHandler::DispatchMouseDown)
  758.  
  759. FW_Handled CMouseUpBehavior::DoMouseUp(Environment* ev, const FW_CMouseEvent& theMouseEvent) 
  760. {
  761. FW_UNUSED(theMouseEvent);
  762.     // Enable the "Delete" button if there are 1 or more selected items
  763.     if (fListBox->GetSelectedItem(ev) > 0)
  764.     {
  765.         FW_CSuperView* formView = fListBox->GetSuperView(ev);
  766.         FW_CButton* rmButton = (FW_CButton*)formView->FindViewByID(ev, kRemoveButtonID);
  767.         FW_ASSERT(rmButton);
  768.         rmButton->Enable(ev);
  769.     }
  770.  
  771.     // let the list-box handle its mouse up event (although it doesn't matter here)
  772.     return FW_kNotHandled;
  773. }
  774.